import mountElement from './mountElement';
import updateTextNode from './updateTextNode';
import updateNodeElement from './updateNodeElement';
import createDOMElement from "./createDOMElement";
import unmountNode from "./unmountNode";
import diffComponent from "./diffComponent";

// 深度优先遍历 ==> 先把当前元素和他的子节点全部处理完成以后，再去进行diff下一个兄弟节点
// 只对比同级节点
export default function diff(vDom, container, oldDom) {
  // 获取老的虚拟dom节点
  const oldVDOM = oldDom && oldDom._vitualDOM;
  // 获取组件实例
  const oldComponent = oldVDOM && oldVDOM.component;
  // 判断oldDOM是否存在
  if (!oldDom) {
    mountElement(vDom, container);
    // 如果节点类型不相同,还需要去除掉组件,因为组件的类型是function
  } else if (vDom.type !== oldVDOM.type && typeof vDom.type !== 'function') {
    const newEle = createDOMElement(vDom);
    // 使用新创建好的dom节点，替换老的dom节点即可
    oldDom.parentNode.replaceChild(newEle, oldDom);
  } else if (typeof vDom.type === 'function') {
    //  code ...
    // console.dir(oldDom._vitualDOM.component);
    diffComponent(vDom, oldComponent, oldDom, container);
  } else if (oldVDOM && oldVDOM.type === vDom.type) {
    // 如果新旧节点的类型相同表示当前节点是可以复用的，所以更新内部的内容即可
    if (vDom.type === 'text') {
      // 更新内容
      updateTextNode(vDom, oldVDOM, oldDom);
    } else {
      // 元素节点 对比元素属性是否发生变化
      updateNodeElement(oldDom, vDom, oldVDOM);
    }

    vDom.props.children.forEach((child, i) => {
      diff(child, oldDom, oldDom.childNodes[i]);
    });

    // 删除节点
    // 获取旧节点的数量
    let oldChildNodes = oldDom.childNodes;

    // 如果满足条件：如果老节点的个数大于新节点个数，多出去的直接删除
    // 因为前面的节点会直接更新内容
    // 结果：界面呈现内容跟新节点内容一致，老的多出去的直接干掉

    if (oldChildNodes.length > vDom.props.children.length) {
      for (let i = oldChildNodes.length - 1; i > vDom.children.length - 1; i--) {
        unmountNode(oldChildNodes[i]);
      }
    }
  }
}
